#ifndef AWOPERATION
#define AWOPERATION

#include "VMPFocus.hpp"


cText TEXT_ELEMENT="element";



//Interface - Extern Operation Releated Properties
	StrHashmap<ptrOperation>    Operations;
	cList<ptrOperation>         lsOperations;

	int OP_EXT_PRIORITY=0;

/*
Priority:
17: () (){}
16: name number [] x() .
15: ! &name
14: -x +x
13: * / %
12: + -
10: < > <= >=
 9: == !=
 5: &&
 4: ||
 2: =

simple-divide:
expression: () name number  [] x() ! &name -x +x * / % + - < > <= >= == != && || =
 statement: var static if for while do continue break return
     blank: spacings, quote
*/


class ERR_NO_PRIORITY{};

StrHashmap<int> PriorityList;

void loadlsPriority(){
	PriorityList.push("()",17);
	PriorityList.push("(){}",16);
	PriorityList.push("name",16);
	PriorityList.push("number",16);
	PriorityList.push("text",16);
	PriorityList.push("[]",16);
	PriorityList.push(".",16);
	PriorityList.push("x()",16);
	PriorityList.push("!",15);
	PriorityList.push("&name",15);
	PriorityList.push("-x",11);
	PriorityList.push("+x",11);
	PriorityList.push("*",13);
	PriorityList.push("/",13);
	PriorityList.push("%",13);
	PriorityList.push("+",12);
	PriorityList.push("-",12);
	PriorityList.push("<",10);
	PriorityList.push(">",10);
	PriorityList.push(">=",10);
	PriorityList.push("<=",10);
	PriorityList.push("==",9);
	PriorityList.push("!=",9);
	PriorityList.push("&&",5);
	PriorityList.push("||",4);
	PriorityList.push("=",2);
}
void loadPriority(){
	loadlsPriority();

	for (int i=0; i<lsOperations.length(); ++i)
		lsOperations[i]->Extended.push(
			OP_EXT_PRIORITY,
			(void*)(PriorityList.search(lsOperations[i]->Name))
		);
}

cText TEXT_PRIORITY_SAME="same";
cText TEXT_PRIORITY_HIGHER="higher";
cText TEXT_PRIORITY_LOWER="lower";
cText TEXT_PRIORITY_BLANK="blank";

void fPreL_priority(ptrText name, ListIdentity* what){
	int* current=(int*)((*Operations.search(*name))->Extended.search(OP_EXT_PRIORITY));
	if (!current) throw ERR_NO_PRIORITY();
	//cout<<"priority "<<*name<<':'<<*current<<endl;
	ListIdentity::iterator i;
	for(i=what->begin(); i!=what->end(); ++i){
		ptrIdentity tmp=*i;
		int* tmpR=(int*)(tmp->Operation->Extended.search(OP_EXT_PRIORITY));
		if (tmpR)
			tmp->Identifier=
				(*tmpR==*current?	&TEXT_PRIORITY_SAME:
				(*tmpR>*current?	&TEXT_PRIORITY_HIGHER:
									&TEXT_PRIORITY_LOWER)
			);
		else
			tmp->Identifier=			&TEXT_PRIORITY_BLANK;
	};
};


void ParserRename(ListIdentity* what, cText& text){
	ptrOperation opN=Operations[text];
	for(int i=0; i<what->length(); ++i){
		if ((*what)[i]->Operation==opN)
			(*what)[i]->Identifier=&text;
	};
};
void ParserRename(ListIdentity* what, cText text, cText& toText){
	ptrOperation opN=Operations[text];
	for(int i=0; i<what->length(); ++i){
		if ((*what)[i]->Operation==opN)
			(*what)[i]->Identifier=&toText;
	};
};



StrHashmap<bool> ExpressionList;
//expression:0, statement:1, statements:2..

void loadExpList(){
	ExpressionList.push("()",0);
	ExpressionList.push("(){}",0);
	ExpressionList.push("name",0);
	ExpressionList.push("number",0);
	ExpressionList.push("[]",0);
	ExpressionList.push("x()",0);
	ExpressionList.push("!",0);
	ExpressionList.push("&name",0);
	ExpressionList.push("-x",0);
	ExpressionList.push("+x",0);
	ExpressionList.push("*",0);
	ExpressionList.push("/",0);
	ExpressionList.push("%",0);
	ExpressionList.push("+",0);
	ExpressionList.push("-",0);
	ExpressionList.push("<",0);
	ExpressionList.push(">",0);
	ExpressionList.push(">=",0);
	ExpressionList.push("<=",0);
	ExpressionList.push("==",0);
	ExpressionList.push("!=",0);
	ExpressionList.push("&&",0);
	ExpressionList.push("||",0);
	ExpressionList.push("=",0);
}

bool isExpression(){
	return true;////////!!!!!!!!!!!
};

/*
void fPreL_seb(ListIdentity* what){
	for(int i=0; i<what->length(); ++i){
		ptrIdentity tmp=(*what)[i];
		SE_RECORD* tmpR=SE_LIST.search(tmp->Operation->name);
		if (tmpR)
			tmp->Identifier=tmpR->type;	//SE_LIST example: addition->expression|if->statement|block->block, etc...
		else
			tmp->Identifier=LINING_BLANK;
	};
}
*/


//----------------------Operation lists:

#include "op name.hpp"
#include "op x().hpp"
#include "op point.hpp"
#include "op text.hpp"
#include "op (){}.hpp"
#include "op {}.hpp"
#include "op return.hpp"
#include "op var.hpp"
#include "hlp blank.hpp"
#include "op static.hpp"
#include "op =.hpp"
#include "op @.hpp"
#include "op $.hpp"
#include "hlp input.hpp"

#include "SystemDough.hpp"

void initLsOperations(){
	StrHashmap<ptrOperation>::iterator Ti;
	lsOperations.clear();
//	bool OpFound=false;
	for (Ti=Operations.begin(); Ti!=Operations.end(); ++Ti)
		lsOperations.push(Ti->second);
}

void loadOperations(){
	Operations.push(TEXT_NAME,loadOpName());
	Operations.push(".",loadOpPoint());
	Operations.push(TEXT_TEXT,loadOpText());
	Operations.push("x()",loadOpXE());
	Operations.push(TEXT_BLOCK,loadOpB());
	Operations.push("(){}",loadOpDD());
	Operations.push("return",loadOpRet());
	Operations.push(TEXT_BLANK,loadHlpBlank());
	Operations.push("var",loadOpVar());
	Operations.push("static",loadOpSta());
	Operations.push("@",loadOpAP());
	Operations.push("$",loadOpGS());
	Operations.push("input",loadHlpInput());
	//Operations.push(TEXT_ASSIGN,loadOpAssign());

	initLsOperations();

	loadPriority();
};

#endif